#include <cstddef>
#include <iostream>
#include <string>
#include <cstring>
#include <ostream>
using namespace std;

class String{
	friend String operator+(string s1,String&s2)
	{
		String s;
		s.len=s2.len+s1.length();
		if(s.str!=NULL){
			delete [] s.str;
			s.str=NULL;
		}
		s.str=new char[s.len+1];
		char *temp=new char[s.len+1];//Attention!-->the length must be s
		strcpy(temp,s1.c_str());
		temp[s1.length()]=0;
		strcat(temp,s2.str);
		strcpy(s.str,temp);
		s.str[s.len]=0;
		delete [] temp;
		temp=NULL;
		return s;
	}
	friend ostream&operator<<(ostream &out,String &s)
	{
		out<<s.str;
		return out;
	}
	friend istream&operator>>(istream &in,String &s)
	{
		char temp[CINLIM];
		in.get(temp,CINLIM,'\n');
		if(in){
			s=temp;
		}
		while (in&&in.get()!='\n') {
			continue;
		}
		in.clear();
		return in;
	}
	friend bool operator==(const String&s1,const String s2)
	{
		if(strcmp(s1.str,s2.str)==0){
			return true;
		}else {
			return false;
		}
	}
	private:
		char *str;
		int len;
		static int num_strings;
		static const int CINLIM=80;
	public:
		//constructors and other methods
		String(const char *s)
		{
			this->len=strlen(s);
			this->str=new char[len+1];
			strcpy(this->str,s);
			num_strings++;
		}
		String()
		{
			this->len=4;
			str=new char[1];
			str[0]=0;
			num_strings++;
		}
		String(const String &s)
		{
			num_strings++;
			len=s.len;
			str=new char[len+1];
			strcpy(str,s.str);
		}
		~String()
		{
			num_strings--;
			delete [] str;
			str=NULL;
		}
		int lenth()const{return len;}

		//overloaded operator methods
		String &operator=(const String&s)
		{
			if(this==&s){
				return *this;
			}
			delete [] str;
			len=s.len;
			str=new char[len+1];
			strcpy(str,s.str);
			return *this;
		}
		int has(char target)
		{
			int cnt=0;
			for(int i=0;i<len;i++){
				if(this->str[i]==target){
					cnt++;
				}
			}
			return cnt;
		}
		void stringup()
		{
			for(int i=0;i<this->len;i++){
				if(this->str[i]>='a'&&this->str[i]<='z'){
					this->str[i]=this->str[i]+'A'-'a';
				}
			}
		}
		void stringlow()
		{
			for(int i=0;i<this->len;i++){
				if(this->str[i]>='A'&&this->str[i]<='Z'){
					this->str[i]=this->str[i]-'A'+'a';
				}
			}
		}
		String operator+(String &s)
		{
			this->len+=s.len;
			char *temp=new char[this->len+1];
			strcpy(temp,this->str);
			strcat(temp,s.str);
			temp[this->len]=0;
			delete [] this->str;
			this->str=temp;
			temp=NULL;
			return *this;
		}
};
int String::num_strings=0;
int main()
{
	String s1(" and I am a C++ student.");
	String s2 = "Please enter your name:\n";
	String s3;
	cout << s2; // overloaded << operator
	cin >> s3; // overloaded >> operator
	s2 = "My name is " + s3; // overloaded =, + operators
	cout << s2 << ".\n";
	s2 = s2 + s1;
	s2.stringup(); // converts string to uppercase
	cout << "The string " << s2 << "\ncontains " << s2.has('A')
		<< " 'A' characters in it.\n";
	s1 = "red"; // String(const char *),
				// then String & operator=(const String&)
	String rgb[3] = { String(s1), String("green"), String("blue")};
	cout << "Enter the name of a primary color for mixing light:\n";
	String ans;
	bool success = false;
	while (cin >> ans){
	ans.stringlow(); // converts string to lowercase
	for (int i = 0; i < 3; i++){
		if (ans == rgb[i]) // overloaded == operator
		{
			cout << "That's right!\n";
			success = true;
			break;
		}
		}
		if (success)
			break;
		else
		cout << "Try again!\n";
	}
	cout << "Bye\n";
	return 0;
}
